/*
 * Copyright (c) 2021 KaiHong Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "hos_init.h"
#include "cmsis_os2.h"
#include "wifi_device.h"
#include "wifi_hotspot.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include "softap.h"
#include "sta.h"
#include <app_demo_uart.h>
#include <hi_types_base.h>
#include "savewifi.h"
#include <netinet/in.h> 
#include "lwip/sockets.h"

#include <app_demo_uart.h>


extern hi_u8 Get_XL;//心率
extern hi_u8 Get_XY;//血氧
extern hi_u8 Get_GY;//高压
extern hi_u8 Get_DY;//低压
extern hi_u8 sta_con_flag;
const char* MY_ip = "43.142.133.176";
unsigned short my_port = 8080;

char request[] = "sb";
char response[128] = "";
extern hi_u8 sta_con_flag;
hi_u8 get_XYG[16];

int SET_SOCKET_ID;

static void PrintLinkedInfo(WifiLinkedInfo* info)
{
    if (!info) return;

    static char macAddress[32] = {0};
    unsigned char* mac = info->bssid;
    snprintf(macAddress, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    printf("bssid: %s, rssi: %d, connState: %d, reason: %d, ssid: %s\r\n",
        macAddress, info->rssi, info->connState, info->disconnectedReason, info->ssid);
}

static int g_connected = 0;
static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
{
    if (!info) return;

    printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
    PrintLinkedInfo(info);

    if (state == WIFI_STATE_AVALIABLE) {
        g_connected = 1;
    } else {
        g_connected = 0;
    }
}

static void OnWifiScanStateChanged(int state, int size)
{
    printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
}

hi_u8 SEND_BUFF_ON[2] = {0X8A,0X8A};
hi_u8 SEND_BUFF_OF[2] = {0X88,0X88};

static BOOL Wifi_SOCKET_RUN(void)
{
    ssize_t retval = 0;

    while(1)
    {

    retval = recv(SET_SOCKET_ID, &response, sizeof(response), 0);
        if(retval>0)
    {
        response[retval] = '\0';
        if(response[0] == 'o')
        {
            printf("send open!\r\n");
             hi_uart_write(DEMO_UART_NUM, SEND_BUFF_ON, 1);
        }else if(response[0] == 'c')
        {
            Get_XL = 0;
            Get_XY = 0;
            Get_DY = 0;
            Get_DY = 0;
             hi_uart_write(DEMO_UART_NUM, SEND_BUFF_OF, 1);
            printf("send close!\r\n");
        }else if(response[0] == 'g')
        {
            printf("send gggg!\r\n");
            goto do_cleanup;
        }
    }

    }
    do_cleanup:
    printf("do_cleanup...\r\n");
    closesocket(SET_SOCKET_ID);
}

void Wifi_SOCKET_GET(void)
{
    osThreadAttr_t attr;

    attr.name = "Wifi_SOCKET_RUN";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 2048;
    attr.priority = 25;

    if (osThreadNew((osThreadFunc_t)Wifi_SOCKET_RUN, NULL, &attr) == NULL)
    {
        printf("Falied to create WifiAPTask!\r\n");
    }
}





void TcpClientTest(const char* host, unsigned short port)
{
    ssize_t retval = 0;
    int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
    SET_SOCKET_ID = sockfd;
    struct sockaddr_in serverAddr = {0};
    serverAddr.sin_family = AF_INET;  // AF_INET表示IPv4协议
    serverAddr.sin_port = htons(port);  // 端口号，从主机字节序转为网络字节序
    if (inet_pton(AF_INET, host, &serverAddr.sin_addr) <= 0) {  // 将主机IP地址从“点分十进制”字符串 转化为 标准格式（32位整数）
        printf("inet_pton failed!\r\n");
        goto do_cleanup;
    }

    // 尝试和目标主机建立连接，连接成功会返回0 ，失败返回 -1
    if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
        printf("connect failed!\r\n");
        goto do_cleanup;
    }
    printf("connect to server %s success!\r\n", host);
    Wifi_SOCKET_GET();

while (1)
{
    osDelay(500);

        sta_con_flag = 0;
        get_XYG[0] = 's';
        get_XYG[1] = '1';
        get_XYG[2] = Get_DY / 100 + '0';
        get_XYG[3] = Get_DY / 10 %10 + '0';
        get_XYG[4] = Get_DY % 10+ '0';

        get_XYG[5] = Get_GY / 100 + '0';
        get_XYG[6] = Get_GY / 10 %10 + '0';
        get_XYG[7] = Get_GY % 10+ '0';

        get_XYG[8] = Get_XL / 100 + '0';
        get_XYG[9] = Get_XL / 10 %10 + '0';
        get_XYG[10] = Get_XL % 10+ '0';  

        get_XYG[11] = Get_XY / 100 + '0';
        get_XYG[12] = Get_XY / 10 %10 + '0';
        get_XYG[13] = Get_XY % 10+ '0';  

        retval = send(sockfd, get_XYG, 14,0);

    
    /* code */
}

    // 建立连接成功之后，这个TCP socket描述符 —— sockfd 就具有了 “连接状态”，发送、接收 对端都是 connect 参数指定的目标主机和端口
    /*
    retval = send(sockfd, request, sizeof(request), 0);
    if (retval < 0) {
        printf("send request failed!\r\n");
        goto do_cleanup;
    }
    printf("send request{%s} %ld to server done!\r\n", request, retval);

     retval = recv(sockfd, &response, sizeof(response), 0);
    if (retval <= 0) {
        printf("send response from server failed or done, %ld!\r\n", retval);
        goto do_cleanup;
    }
    response[retval] = '\0';
    printf("recv response{%s} %ld from server done!\r\n", response, retval); */

    do_cleanup:
    printf("do_cleanup...\r\n");
    closesocket(sockfd);
}

void SEND_get_DATA(const char* host, unsigned short port)
{
    ssize_t retval = 0;
    int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket

    struct sockaddr_in serverAddr = {0};
    serverAddr.sin_family = AF_INET;  // AF_INET表示IPv4协议
    serverAddr.sin_port = htons(port);  // 端口号，从主机字节序转为网络字节序
    if (inet_pton(AF_INET, host, &serverAddr.sin_addr) <= 0) {  // 将主机IP地址从“点分十进制”字符串 转化为 标准格式（32位整数）
        printf("inet_pton failed!\r\n");
        goto do_cleanup;
    }

    // 尝试和目标主机建立连接，连接成功会返回0 ，失败返回 -1
    if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
        printf("connect failed!\r\n");
        goto do_cleanup;
    }
    printf("connect to server %s success!\r\n", host);

    // 建立连接成功之后，这个TCP socket描述符 —— sockfd 就具有了 “连接状态”，发送、接收 对端都是 connect 参数指定的目标主机和端口

    get_XYG[0] = 's';
    get_XYG[1] = '1';
    get_XYG[2] = Get_DY / 100 + '0';
    get_XYG[3] = Get_DY / 10 %10 + '0';
    get_XYG[4] = Get_DY % 10+ '0';

    get_XYG[5] = Get_GY / 100 + '0';
    get_XYG[6] = Get_GY / 10 %10 + '0';
    get_XYG[7] = Get_GY % 10+ '0';

    get_XYG[8] = Get_XL / 100 + '0';
    get_XYG[9] = Get_XL / 10 %10 + '0';
    get_XYG[10] = Get_XL % 10+ '0';  

    get_XYG[11] = Get_XY / 100 + '0';
    get_XYG[12] = Get_XY / 10 %10 + '0';
    get_XYG[13] = Get_XY % 10+ '0';  

    retval = send(sockfd, get_XYG, 14,0);
    if (retval < 0) {
        printf("send request failed!\r\n");
        goto do_cleanup;
    }
    osDelay(12);


   // printf("send request{%s} %ld to server done!\r\n", request, retval);

/*     retval = recv(sockfd, &response, sizeof(response), 0);
    if (retval <= 0) {
        printf("send response from server failed or done, %ld!\r\n", retval);
        goto do_cleanup;
    }
    response[retval] = '\0';
    printf("recv response{%s} %ld from server done!\r\n", response, retval); */

    do_cleanup:
    printf("do_cleanup...\r\n");
    //closesocket(sockfd);
    closesocket(sockfd);
}



int WifiConnect(char *ssid,char *pwd)
{
    
    WifiErrorCode geterrCode;
    WifiEvent eventListener = {
        .OnWifiConnectionChanged = OnWifiConnectionChanged,
        .OnWifiScanStateChanged = OnWifiScanStateChanged
    };
    WifiDeviceConfig apConfig = {};
    int netId = -1;

    osDelay(10);
    geterrCode = RegisterWifiEvent(&eventListener);
    printf("RegisterWifiEvent: %d\r\n", geterrCode);

    // setup your AP params
    strcpy(apConfig.ssid, ssid);
    strcpy(apConfig.preSharedKey, pwd);
    apConfig.securityType = WIFI_SEC_TYPE_PSK;

    while (1) {
        geterrCode = EnableWifi();
        printf("EnableWifi: %d\r\n", geterrCode);
        osDelay(10);

        geterrCode = AddDeviceConfig(&apConfig, &netId);
        printf("AddDeviceConfig: %d\r\n", geterrCode);

        g_connected = 0;
        geterrCode = ConnectTo(netId);
        if(geterrCode!=0)
        {
            return -1;
        }
        printf("ConnectTo(%d): %d\r\n", netId, geterrCode);

        while (!g_connected) {
            osDelay(10);
        }
        printf("g_connected: %d\r\n", g_connected);
        if_get_wifi_flag = 1;
        osDelay(50);
        WR_WIFI_SSID(ssid);
        WR_WIFI_PWSD(pwd);
        // 联网业务开始
        struct netif* iface = netifapi_netif_find("wlan0");
        if (iface) {
            err_t ret = netifapi_dhcp_start(iface);
            printf("netifapi_dhcp_start: %d\r\n", ret);

            osDelay(200); // wait DHCP server give me IP
            ret = netifapi_netif_common(iface, dhcp_clients_info_show, NULL);
            printf("netifapi_netif_common: %d\r\n", ret);
        }
        sta_con_flag = 1;
       // TcpClientTest(test_ip,test_port);
        TcpClientTest(MY_ip,my_port);
        
        
/*         // 联网业务结束
        err_t ret = netifapi_dhcp_stop(iface);
        printf("netifapi_dhcp_stop: %d\r\n", ret);

        Disconnect(); // disconnect with your AP

        RemoveDevice(netId); // remove AP config
        geterrCode = DisableWifi();
        osDelay(200); */
    }
}

